package cn.yougou.serviceImpl;

import cn.yougou.common.AnalysisFileUtil;
import cn.yougou.common.CalculateUtil;
import cn.yougou.mapper.YgCommodityProductMapper;
import cn.yougou.mapper.YgOrderMapper;
import cn.yougou.pojo.YgCommodityProduct;
import cn.yougou.pojo.YgCoupons;
import cn.yougou.pojo.YgOrder;
import cn.yougou.pojo.YgUserCoupons;
import cn.yougou.service.YgCouponRules;
import cn.yougou.service.YgUserCouponsService;
import cn.yougou.service.shopcart.YgCommodityProductService;
import cn.yougou.service.shopcart.YgCommodityService;
import cn.yougou.service.shopcart.YgCouponsService;

import cn.yougou.service.user.YgOrderService;
import cn.yougou.vo.*;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: DELL
 * @date: 2021/1/3 15:02
 * @description:
 */
@Service
public class YgCouponRulesImpl implements YgCouponRules {
    @Reference(check = false)
    private YgOrderService ygOrderService;

    @Autowired
    private YgCouponsService ygCouponsService;
    @Autowired
    private YgCommodityService ygCommodityService;
    @Autowired
    private AnalysisFileUtil analysisFileUtil;
    @Autowired
    YgCommodityProductService ygCommodityProductService;
    @Autowired
    private YgCommodityProductMapper ygCommodityProductMapper;
    @Autowired
    private YgUserCouponsService ygUserCouponsService;
    //返回一个减免结果，将 List<YgResCommodityVo>数据处理，满足优惠券的商品拼接成有减免数据的字符串
    @Override
    public YgCouponDerateResultVo getDerateResult(YgUserCoupons ygUserCoupons, YgResOrderVo ygResOrderVo) {
        List<YgResCommodityVo> getjudge = Getjudge(ygUserCoupons, ygResOrderVo);
        if(getjudge!=null){
            if(getjudge.size()==1){//单个商品满足的计算方式
                //查出商品pojo
                YgCommodityProduct product =  ygCommodityProductMapper.queryAll( new YgCommodityProduct(getjudge.get(0).getProductid()));
                YgCommodityVo ygCommodityVo = ygCommodityService.queryById(getjudge.get(0).getId());
                //获取商品总价格
                double countMoney = getjudge.get(0).getCommodityCount()*getjudge.get(0).getCommodityDouble();
                //判断价格是否大于优惠金额 如果大于则正常返回 如果小于则返回 真实的优惠金额
                if(countMoney>ygUserCoupons.getCouponmoney()){
                  //  System.out.println("id:"+ygUserCoupons.getId());
                  //  System.out.println("countMoney:"+countMoney+" ygUserCoupons.getCouponmoney(): "+ygUserCoupons.getCouponmoney());
                    YgResCommodityVo ygResCommodityVo =new YgResCommodityVo(getjudge.get(0).getOrdersn(),getjudge.get(0).getId(),getjudge.get(0).getCommodityname(),getjudge.get(0).getProductid(),getjudge.get(0).getCommodityCount(),getjudge.get(0).getCommodityDouble(),ygUserCoupons.getCouponmoney(),ygCommodityVo.getDiscount(),product.getPrice());

                    List<YgResCommodityVo> data = new ArrayList<> ();
                    data.add(ygResCommodityVo);
                    //在返回之前将 其他商品信息插入至data
                    fillData(ygResOrderVo,data);
                    String orderDate = JSON.toJSONString(data);
                    return new YgCouponDerateResultVo(orderDate,ygUserCoupons.getCouponmoney());
                }else{
                    YgResCommodityVo ygResCommodityVo =new YgResCommodityVo(getjudge.get(0).getOrdersn(),getjudge.get(0).getId(),getjudge.get(0).getCommodityname(),getjudge.get(0).getProductid(),getjudge.get(0).getCommodityCount(),getjudge.get(0).getCommodityDouble(),countMoney,ygCommodityVo.getDiscount(),product.getPrice());
                    List<YgResCommodityVo> data = new ArrayList<> ();
                    data.add(ygResCommodityVo);
                    fillData(ygResOrderVo,data);
                    String orderDate = JSON.toJSONString(data);
                    return new YgCouponDerateResultVo(orderDate,ygUserCoupons.getCouponmoney());
                }
            }

            if(getjudge.size()>1){//存在多数商品满足的计算方式
                YgResCommodityVoSort(getjudge);//对商品进行从大到小排序
                //由多件商品平分
                //计算每个商品应该分摊多少钱
                double ApportionPrice = CalculateUtil.getApportionPrice(ygUserCoupons.getCouponmoney(),getjudge);
                double difference =ygUserCoupons.getCouponmoney()-(ApportionPrice*CalculateUtil.geiCount(getjudge));

                if(ApportionPrice>0.0){
                    List<YgResCommodityVo> data = new ArrayList<> ();
                    for(int i =0;i<getjudge.size();i++){
                        //查出商品pojo
                        YgCommodityProduct product = ygCommodityProductMapper.queryAll( new YgCommodityProduct(getjudge.get(i).getProductid()));
                        YgCommodityVo ygCommodityVo = ygCommodityService.queryById(getjudge.get(i).getId());
                        //获取商品总价格
                        double countMoney = getjudge.get(i).getCommodityCount()*getjudge.get(i).getCommodityDouble();
                        if(i==0){
                           if(countMoney>ApportionPrice+difference){
                               data.add(new YgResCommodityVo(getjudge.get(0).getOrdersn(),getjudge.get(i).getId(),getjudge.get(i).getCommodityname(),getjudge.get(0).getProductid(),getjudge.get(i).getCommodityCount(),getjudge.get(i).getCommodityDouble(),(ApportionPrice*getjudge.get(i).getCommodityCount())+difference,ygCommodityVo.getDiscount(),product.getPrice()));
                           }else{
                               data.add(new YgResCommodityVo(getjudge.get(0).getOrdersn(),getjudge.get(i).getId(),getjudge.get(i).getCommodityname(),getjudge.get(0).getProductid(),getjudge.get(i).getCommodityCount(),getjudge.get(i).getCommodityDouble(), countMoney*getjudge.get(i).getCommodityCount(),ygCommodityVo.getDiscount(),product.getPrice()));

                           }
                       continue;
                        }

                        if(countMoney>ApportionPrice+difference){
                            data.add(new YgResCommodityVo(getjudge.get(0).getOrdersn(),getjudge.get(i).getId(),getjudge.get(i).getCommodityname(),getjudge.get(0).getProductid(),getjudge.get(i).getCommodityCount(),getjudge.get(i).getCommodityDouble(), ApportionPrice*getjudge.get(i).getCommodityCount(),ygCommodityVo.getDiscount(),product.getPrice()));
                        }else{
                            data.add(new YgResCommodityVo(getjudge.get(0).getOrdersn(),getjudge.get(i).getId(),getjudge.get(i).getCommodityname(),getjudge.get(0).getProductid(),getjudge.get(i).getCommodityCount(),getjudge.get(i).getCommodityDouble(),countMoney*getjudge.get(i).getCommodityCount(),ygCommodityVo.getDiscount(),product.getPrice()));
                        }
                    }
                    //获得实际优惠价格
                    fillData(ygResOrderVo,data);
                    String orderDate = JSON.toJSONString(data);
                    return new YgCouponDerateResultVo(orderDate,getActualpreferentialprice(data));
                }
            }
            }else{
                    if(ygResOrderVo.getYgResCommodityVos()!=null){
                //如果没有选择优惠券则返回正常数据
                //获取商品列表
                YgResCommodityVo[] ygResCommodityVos = ygResOrderVo.getYgResCommodityVos();
                for(int i =0;i<ygResCommodityVos.length;i++){
                    System.out.println(ygResCommodityVos[i].toString());
                }
                List<YgResCommodityVo> data = new ArrayList<> ();
                if(ygResCommodityVos!=null){

                    for(int i =0;i<ygResCommodityVos.length;i++){
                        //查出商品pojo
                        YgCommodityProduct product = ygCommodityProductMapper.queryAll( new YgCommodityProduct(ygResCommodityVos[i].getProductid()));

                        YgCommodityVo ygCommodityVo = ygCommodityService.queryById(ygResCommodityVos[i].getId());
                        //没有选择优惠券的情况
                        data.add(new YgResCommodityVo(ygResCommodityVos[i].getOrdersn(),
                                ygResCommodityVos[i].getId(),
                                ygResCommodityVos[i].getCommodityname(),
                                ygResCommodityVos[i].getProductid(),
                                ygResCommodityVos[i].getCommodityCount(),
                                ygResCommodityVos[i].getCommodityDouble(),
                                0.0,
                                ygCommodityVo.getDiscount(),
                                product.getPrice()));
                    }
                    String orderDate = JSON.toJSONString(data);
                    return new YgCouponDerateResultVo(orderDate,0);
                }
            }
        }

        return  null;
    }

    @Override
    public void test() {
        System.out.println("ssssssssssssssssssssssssssssss");
    }



    /**
     * 将所有数据都填充到 data
     * */
   private void fillData(YgResOrderVo ygResOrderVo,List<YgResCommodityVo> data){
       YgResCommodityVo[] ygResCommodityVos = ygResOrderVo.getYgResCommodityVos();
       if(ygResCommodityVos!=null){
            for(int i =0;i<ygResCommodityVos.length;i++){
                boolean flag = true;
                for(int a =0;a<data.size();a++){
                    if(ygResCommodityVos[i].getId().toString().equals(data.get(a).getId().toString())){
                        flag =false;
                        break;//ri
                    }
                }
             if(flag){
                 //查出商品pojo
                 YgCommodityProduct product = ygCommodityProductMapper.queryAll( new YgCommodityProduct(ygResCommodityVos[i].getProductid()));
                 YgCommodityVo ygCommodityVo = ygCommodityService.queryById(ygResCommodityVos[i].getId());
                 //没有选择优惠券的情况
                 data.add(new YgResCommodityVo(ygResCommodityVos[i].getOrdersn(),ygResCommodityVos[i].getId(),ygResCommodityVos[i].getCommodityname(),ygResCommodityVos[i].getProductid(),ygResCommodityVos[i].getCommodityCount(),ygResCommodityVos[i].getCommodityDouble(),0.0,ygCommodityVo.getDiscount(),product.getPrice()));
             }
            }
        }
   }

    /**
     * 商品详情 commodityData 将商品实时情况存储 商品id 商品名称 商品 GetOrderInfoYgResOrderVo()
     * */

    /**
   * 获得实际优惠价格
   * */
  public double getActualpreferentialprice(List<YgResCommodityVo> data){
      double count=0.0;
      if(data !=null){
          for(int i =0;i<data.size(); i++){
              count+=data.get(i).getDerateResultMoney();
          }
      }
      BigDecimal b   =   new   BigDecimal(count);
      double   f1   =   b.setScale(2,   BigDecimal.ROUND_HALF_UP).doubleValue();
      return f1;

  }
/**
 *
 * 对商品列表进行排序 按照 商品的价格
 * */
    public void  YgResCommodityVoSort(List<YgResCommodityVo> getjudge){
       YgResCommodityVo middle =null;
        for(int i =0;i< getjudge.size()-1;i++){
            for(int a =0;a<getjudge.size()-1-i; a++){
                    //判断
                double value1 =getjudge.get(a).getCommodityCount()*getjudge.get(a).getCommodityDouble();
                double value2 =getjudge.get(a+1).getCommodityCount()*getjudge.get(a+1).getCommodityDouble();
                if(value1<value2){
                    middle =getjudge.get(a+1);//将第二个值存到中间值
                    getjudge.set(a+1,getjudge.get(a));
                    getjudge.set(a,middle);
                }
            }
        }
    }

    //执行方法 判断是否满足条件 如果满足则返回减免金额 如果不满足则返回  0
    @Override
    public List<YgResCommodityVo> Getjudge(YgUserCoupons ygUserCoupons, YgResOrderVo ygResOrderVor) {

        //结构更改
        //首先在判断时返回的数据为 一个可以使用该优惠券的商品的list
        //这个方法 返回该list  这个list中包含的信息就是这个商品列表
        //如果执行的方法返回true 则返回对应优惠券中的 优惠金额
        List<YgResCommodityVo> data =null;
        //判断优惠券状态 如果过期
        boolean flag = loseEfficacy(ygUserCoupons);
        if(!flag ||ygUserCoupons==null){
            return null;
        }
        try {
            Method method = this.getClass().getMethod(ygUserCoupons.getCouponrules().toLowerCase(), YgUserCoupons.class, YgResOrderVo.class);
            data =(List<YgResCommodityVo>)method.invoke(this,ygUserCoupons,ygResOrderVor);

            return data;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            return null;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            return null;
        }
    }

    private boolean loseEfficacy(YgUserCoupons ygUserCoupons) {
        //判断本优惠券是否状态正常
      if(ygUserCoupons!=null){
          if(ygUserCoupons.getState()==0){//0为正常
              //判断优惠券模板是否正常 过期
              YgCoupons ygCoupons = ygCouponsService.queryById(ygUserCoupons.getCouponsid());
              if(ygCoupons!=null){
                  if(ygCoupons.getState()==0){
                      return true;
                  }else {
                      return false;
                  }
              }
          }
      }

        return false;
    }

    //NEWPEOPLE 新人首单 newpeople
    //判断该用户是否 拥有消费完成的订单
    @Override
    public List<YgResCommodityVo> newpeople(YgUserCoupons ygUserCoupons, YgResOrderVo ygResOrderVor) {
        List<YgResCommodityVo>  data = new ArrayList<>();
        //获得商品的 []
        YgResCommodityVo [] ygResCommodityVos = ygResOrderVor.getYgResCommodityVos();
        if(ygResOrderVor!=null){
            Integer result = ygOrderService.getOkOrder(ygResOrderVor.getUserid());
            if(result==0){
                for(int i = 0; i <ygResCommodityVos.length; i++){
                    data.add(ygResCommodityVos[i]);
                }
            }
        }

            //返回做过禁止判断的优惠券的list  结果就是 只要被返回的就是能用的
        return forbidScopeJudge(ygUserCoupons,data);
    }
    //MEET_MONEY 满额优惠 meet_money
    //如果满足价格就返回 优惠价格
    @Override
    public List<YgResCommodityVo> meet_money(YgUserCoupons ygUserCoupons, YgResOrderVo ygResOrderVor) {
        List<YgResCommodityVo>  data = new ArrayList<>();

        //获取 优惠条件
        Double judge = Double.parseDouble(ygUserCoupons.getCouponrulesjudge());
        //获取 商品list
        YgResCommodityVo[] ygResCommodityVos = ygResOrderVor.getYgResCommodityVos();
        if (ygResCommodityVos != null) {
            Double count = 0.0;
            for (int i = 0; i < ygResCommodityVos.length; i++) {
                count += ygResCommodityVos[i].getCommodityCount()*ygResCommodityVos[i].getCommodityDouble();
            }
            //如果 实际价格 大于 优惠条件 则 返回true 满足
            if (count >= judge) {
               for(int i = 0; i <ygResCommodityVos.length; i++){
                   data.add(ygResCommodityVos[i]);
               }
            }
        }
        return forbidScopeJudge(ygUserCoupons,data);
    }
    //MEET_COUNT 满件优惠 meet_count
    // 如果该商品满两件就 满足返回 true
    //并且遍历该优惠卷的 使用范围
    //如果都满足 返回true
    @Override
    public List<YgResCommodityVo> meet_count(YgUserCoupons ygUserCoupons, YgResOrderVo ygResOrderVor) {
        List<YgResCommodityVo>  data = new ArrayList<>();
        //获得商品的 []
        YgResCommodityVo [] ygResCommodityVos = ygResOrderVor.getYgResCommodityVos();
        //遍历
        if(ygResCommodityVos !=null){
            for(int i =0;i<ygResCommodityVos.length;i++){
                //如果 商品总数大于优惠卷限制则 执行 范围判断
                if(ygResCommodityVos[i].getCommodityCount() >Integer.parseInt( ygUserCoupons.getCouponrulesjudge())){
                    data.add(ygResCommodityVos[i]);
                }
            }
        }
        return  forbidScopeJudge(ygUserCoupons,data);
    }
    //MEET_TYPE 类型促销 meet_type
    //查询商品 的类型  在商品中包含了 该类型 则 满足
    //如果满足 返回 true
    @Override
    public List<YgResCommodityVo> meet_type(YgUserCoupons ygUserCoupons, YgResOrderVo ygResOrderVor) {
        List<YgResCommodityVo>  data = new ArrayList<>();
        //通过查出优惠券表的范围
        YgCoupons ygCoupons = ygCouponsService.queryById(ygUserCoupons.getCouponsid());
        List<String> fileAssignLineList = analysisFileUtil.getFileAssignLineList(ygCoupons.getTypeid(), 0);
        //获得商品的 []
        YgResCommodityVo [] ygResCommodityVos = ygResOrderVor.getYgResCommodityVos();
        if(ygResCommodityVos!=null){
            for(int i =0;i<ygResCommodityVos.length;i++){
                //查询出 商品的 三级类目
                try {
                    YgCommodityVo ygCommodityVo = ygCommodityService.queryById(ygResCommodityVos[i].getId());
                    //判断 商品的 三级类目 是否 在 该优惠卷的使用范围
                    for(int l =0;l<fileAssignLineList.size();l++){
                        if(fileAssignLineList.get(l).equals(ygCommodityVo.getCategoryid().toString())){
                            //如果该优惠券的 使用范围包含 该商品的类型id则 可用 返回true
                            data.add(ygResCommodityVos[i]);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return forbidScopeJudge(ygUserCoupons,data);
    }
    //NOTHRESHOLD 无门槛 nothreshold
    @Override
    public List<YgResCommodityVo> nothreshold(YgUserCoupons ygUserCoupons, YgResOrderVo ygResOrderVor) {
        List<YgResCommodityVo>  data = new ArrayList<>();
        //获得商品的 []
        YgResCommodityVo [] ygResCommodityVos = ygResOrderVor.getYgResCommodityVos();
       if(ygResCommodityVos!=null){
           for(int i =0;i<ygResCommodityVos.length;i++){
               data.add(ygResCommodityVos[i]);
           }
       }
        //没问题直接 true
        return forbidScopeJudge(ygUserCoupons,data);
    }
    //执行判断禁止范围
    @Override
    public List<YgResCommodityVo> forbidScopeJudge(YgUserCoupons ygUserCoupons, List<YgResCommodityVo> data) {
        YgCoupons ygCoupons = ygCouponsService.queryById(ygUserCoupons.getCouponsid());
        if(ygCoupons!=null){
            List<String> fileAssignLineList = analysisFileUtil.getFileAssignLineList(ygCoupons.getForbidScope(), 0);
           if(!data.isEmpty()){
               for(int i =0;i < data.size(); i++){
                    for(int a =0;a<fileAssignLineList.size();a++){
                        if(fileAssignLineList.get(a).equals(data.get(i).getId().toString())){
                            data.remove(i);
                        }
                    }
               }
           }

        }
        return data;
    }

}
